package suncertify.gui.panels;

import java.awt.FlowLayout;
import java.awt.geom.IllegalPathStateException;

import javax.swing.JLabel;
import javax.swing.JPanel;

import suncertify.gui.UnsignedIntegerJTextField;

/**
 * Provides a panel that consists of a {@link JLabel} and a {@link UnsignedIntegerJTextField}. The label shows the name
 * of the numeric value, the integer text field has a tool tip that explains the integer value. The panel does not
 * validate the numeric value, this is the responsibility of the caller.
 * 
 * <p>
 * This panel is used in the application to enter the server port value and the contractor customer ID code.
 */
public class NumericValuePanel extends JPanel {

    /**
     * Automatically generated serialization version ID.
     */
    private static final long serialVersionUID = -2593978170278898542L;

    /**
     * Constant of four space characters, used to indent the panel contents.
     */
    private static final String INDENT = "    ";

    /**
     * This label provides the name of the numeric value.
     */
    private JLabel label;

    /**
     * Provides the integer text field.
     */
    private UnsignedIntegerJTextField unsignedIntegerField;

    /**
     * Constructs the class with the specified parameters.
     * 
     * @param defaultValue
     *            Provides the value of the integer text field.
     * @param valueLabel
     *            Provides the text for the label, this text describes the text field e.g. 'Port number:'
     * @param maxValue
     *            Defines the maximum value allowed to be entered in the text field.
     * @param indent
     *            True shifts the panel contents to the left by inserting an invisible {@link JLabel} that contains four
     *            space characters as the first component in the panel. False no indent label is inserted, the panel
     *            contains only the value label and the text field. Use this option to indicate that the panel contents
     *            belongs logically to another control above it e.g. a radio button.
     * @param mnemonicKey
     *            Defines the mnemonic key of the <code>valueLabel</code> parameter.
     * @param tooltip
     *            Provides the tool tip text of the value text field.
     * 
     * @throws IllegalArgumentException
     *             Thrown if:
     *             <ol>
     *             <li>The <code>defaultValue</code> is negative or larger than the <code>maxValue</code> parameter.</li>
     *             <li><The <code>maxValue</code> is negative.</li>
     *             </ol>
     */
    public NumericValuePanel(int defaultValue, String valueLabel, int maxValue, boolean indent, int mnemonicKey,
	    String tooltip) {

	if (defaultValue < 0 || defaultValue > maxValue) {
	    throw new IllegalPathStateException(
		    "NumericValuePanel cannot be constructed with a defaultValue parameter that is negative or greater than the maxValue parameter!");
	}

	if (maxValue < 0) {
	    throw new IllegalPathStateException(
		    "NumericValuePanel cannot be constructed with a negative maxValue parameter!");
	}

	this.setLayout(new FlowLayout(FlowLayout.LEFT));

	this.label = new JLabel(valueLabel);
	this.label.setDisplayedMnemonic(mnemonicKey);

	this.unsignedIntegerField = new UnsignedIntegerJTextField(10, maxValue);
	this.unsignedIntegerField.setText(Integer.toString(defaultValue));
	this.unsignedIntegerField.setToolTipText(tooltip);

	this.label.setLabelFor(this.unsignedIntegerField);

	if (indent) {
	    this.add(new JLabel(INDENT));
	}

	this.add(this.label);
	this.add(this.unsignedIntegerField);
    }

    /**
     * Determines if the integer text field is empty.
     * 
     * @return True if the integer text field is empty, false otherwise.
     */
    public boolean isEmpty() {

	return this.unsignedIntegerField.isEmpty();
    }

    /**
     * Returns the value of the integer text field.
     * 
     * @return The value of the integer text field.
     */
    public int getValue() {

	String textValue = this.unsignedIntegerField.getText().trim();

	return Integer.parseInt(textValue);
    }

    /**
     * Enable/disables the label and text field based on the input parameter.
     * 
     * @param enabled
     *            True to enable the controls, false to disable them.
     */
    public void setEnabledState(boolean enabled) {

	this.label.setEnabled(enabled);
	this.unsignedIntegerField.setEnabled(enabled);
    }
}
